package com.hnchances.wjb.Realm;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hnchances.wjb.Service.UserService;
import com.hnchances.wjb.entity.Role;
import com.hnchances.wjb.entity.User;
import com.hnchances.wjb.jwt.JwtToken;
import com.hnchances.wjb.jwt.JwtUtil;
import com.hnchances.wjb.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    @Autowired
    UserMapper userMapper;
    // 授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = JwtUtil.getUsernameFromToken(principalCollection.toString());
//        User user = userService.getUserByName(username);

        List<Role> user = userMapper.queryByUsername(username);
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // TODO 改为从数据库中获取该用户的角色
        user.stream().map(item ->{
            authorizationInfo.addRole(item.getRole());
            authorizationInfo.addRole(item.getPermission());
            return user;
        }).collect(Collectors.toList());
        /*authorizationInfo.addRole(user.getRole());
        authorizationInfo.addStringPermission(user.getPermission());*/
        return authorizationInfo;
    }

    // 认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("身份认证");
        // 这里的 token是从 JWTFilter 的 executeLogin() 方法传递过来的
        String token = (String) authenticationToken.getCredentials();
        // 解密
        String username = JwtUtil.getUsernameFromToken(token);
        // TODO 改为从数据库获取对应用户名密码的用户
        LambdaQueryWrapper<User> lambdaQueryWrapper =  new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getTrueName,username);
        User user = userService.getOne(lambdaQueryWrapper);
        if (StringUtils.isEmpty(username) || !JwtUtil.verify(token, username)) {
            log.error("token 认证失败");
            throw new AuthenticationException("token 认证失败");
        }
        if (null == user) {
            log.error("账号或密码错误");
            throw new AuthenticationException("账号或密码错误");
        }

        log.info("用户{}认证成功！", user.getTrueName());

        return new SimpleAuthenticationInfo(token, token, getName());
    }
}